From 42dd41e9a442ba40376139af81ecb9571b321a2f Mon Sep 17 00:00:00 2001 From: "kaf24@labyrinth.cl.cam.ac.uk" Date: Wed, 12 Feb 2003 17:36:02 +0000 Subject: [PATCH] bitkeeper revision 1.22.2.14 (3e4a8602WvipwBgbN9VwA2dW6eIyhA) processor.h, traps.c, smpboot.c, process.c: Another fix to fast-trap handling. :-) We needed per-CPU IDTs... --- xen-2.4.16/arch/i386/process.c | 1 - xen-2.4.16/arch/i386/smpboot.c | 13 +++++++++++++ xen-2.4.16/arch/i386/traps.c | 20 +++++++++++++------- xen-2.4.16/include/asm-i386/processor.h | 10 ++++++++-- 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/xen-2.4.16/arch/i386/process.c b/xen-2.4.16/arch/i386/process.c index a23f4b1557..d3cedf4766 100644 --- a/xen-2.4.16/arch/i386/process.c +++ b/xen-2.4.16/arch/i386/process.c @@ -364,7 +364,6 @@ void new_thread(struct task_struct *p, /* NB. prev_p passed in %eax, next_p passed in %edx */ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p) { - extern struct desc_struct idt_table[]; struct thread_struct *prev = &prev_p->thread, *next = &next_p->thread; struct tss_struct *tss = init_tss + smp_processor_id(); diff --git a/xen-2.4.16/arch/i386/smpboot.c b/xen-2.4.16/arch/i386/smpboot.c index dd0f94bd13..f7a5f8f56a 100644 --- a/xen-2.4.16/arch/i386/smpboot.c +++ b/xen-2.4.16/arch/i386/smpboot.c @@ -395,6 +395,10 @@ int cpucount; */ int __init start_secondary(void *unused) { + unsigned int cpu = smp_processor_id(); + /* A 'mem64' suitable for passing to LIDT instruction. */ + unsigned long idt_load[2] = { (IDT_ENTRIES*8)-1, 0 }; + extern void cpu_init(void); /* @@ -408,6 +412,15 @@ int __init start_secondary(void *unused) while (!atomic_read(&smp_commenced)) rep_nop(); + /* + * At this point, boot CPU has fully initialised the IDT. It is + * now safe to make ourselves a private copy. + */ + idt_tables[cpu] = kmalloc(IDT_ENTRIES*8, GFP_KERNEL); + memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*8); + idt_load[2] = (unsigned long)idt_tables[cpu]; + __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) ); + /* * low-memory mappings have been cleared, flush them from the local TLBs * too. diff --git a/xen-2.4.16/arch/i386/traps.c b/xen-2.4.16/arch/i386/traps.c index cdea19eaa6..b8297fe3eb 100644 --- a/xen-2.4.16/arch/i386/traps.c +++ b/xen-2.4.16/arch/i386/traps.c @@ -43,12 +43,10 @@ asmlinkage int hypervisor_call(void); asmlinkage void lcall7(void); asmlinkage void lcall27(void); -/* - * The IDT has to be page-aligned to simplify the Pentium - * F0 0F bug workaround.. We have a special link segment - * for this. - */ -struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, }; +/* Master table, and the one used by CPU0. */ +struct desc_struct idt_table[256] = { {0, 0}, }; +/* All other CPUs have their own copy. */ +struct desc_struct *idt_tables[NR_CPUS] = { 0 }; asmlinkage void divide_error(void); asmlinkage void debug(void); @@ -299,7 +297,12 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code) ti = current->thread.traps + (error_code>>3); if ( ti->dpl >= (regs->xcs & 3) ) { - if ( (error_code>>3)==0x80 ) { printk("!!!\n"); BUG(); } + /* XXX Kill next conditional soon :-) XXX */ + if ( (error_code>>3)==0x80 ) + { + printk("DIDN'T USE FAST-TRAP HANDLER FOR 0x80!!! :-(\n"); + BUG(); + } gtb->flags = GTBF_TRAP_NOCODE; gtb->cs = ti->cs; gtb->eip = ti->address; @@ -542,6 +545,9 @@ void __init trap_init(void) /* Only ring 1 can access monitor services. */ _set_gate(idt_table+HYPERVISOR_CALL_VECTOR,15,1,&hypervisor_call); + /* CPU0 uses the master IDT. */ + idt_tables[0] = idt_table; + /* * Should be a barrier for any external CPU state. */ diff --git a/xen-2.4.16/include/asm-i386/processor.h b/xen-2.4.16/include/asm-i386/processor.h index f7f949d82b..36a50b2976 100644 --- a/xen-2.4.16/include/asm-i386/processor.h +++ b/xen-2.4.16/include/asm-i386/processor.h @@ -358,16 +358,22 @@ struct thread_struct { trap_info_t traps[256]; }; +#define IDT_ENTRIES 256 +extern struct desc_struct idt_table[]; +extern struct desc_struct *idt_tables[]; + #define SET_DEFAULT_FAST_TRAP(_p) \ (_p)->fast_trap_idx = 0x20; \ (_p)->fast_trap_desc.a = 0; \ (_p)->fast_trap_desc.b = 0; #define CLEAR_FAST_TRAP(_p) \ - (memset(idt_table + (_p)->fast_trap_idx, 0, 8)) + (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \ + 0, 8)) #define SET_FAST_TRAP(_p) \ - (memcpy(idt_table + (_p)->fast_trap_idx, &((_p)->fast_trap_desc), 8)) + (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \ + &((_p)->fast_trap_desc), 8)) #define INIT_THREAD { \ sizeof(idle0_stack) + (long) &idle0_stack, /* esp0 */ \ -- 2.30.2